package controller;

import entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * Author:shixiaojun@itany.com
 * Date:2022/5/20 11:08
 * Version:1.0-SNAPSHOT
 * Description:
 */
// 可以使用RestController代替原有的Controller注解
// 当类被@RestController进行标注时
// 表示当前类中的所有方法均不再返回视图
// 而是只返回数据模型
// 相当于该类中的所有方法默认自动添加@ResponseBody注解
@Controller
//@RestController
@RequestMapping("/login")
public class LoginController {

    @RequestMapping("/f1")
    public ModelAndView f1(){
        ModelAndView mav = new ModelAndView();
        mav.setViewName("login");
        return mav;
    }

    @RequestMapping("/f2")
    public String f2(){
        // Handler方法可以直接返回字符串
        // 其效果相当于返回ModelAndView时只设置视图名
        // 方法返回|值用于与mav.setViewName("viewName")方法中参数viewName用法完全一致
        return "login";
    }

    // 对于字符串的返回值,存在三种用法
    // 1.return "值"
        // 直接返回字符串,此时的字符串时作为视图名返回
        // 因此需要经过viewResolver处理
        // 最终访问的视图为:prefix+返回值+suffix
    // 2.return "redirect:url"
        // 通过重定向访问指定的url地址
    // 3.return "forward:url"
        // 通过转发访问指定的url地址
    @RequestMapping("/f3")
    public String f3(){
        return "redirect:/showLogin";
    }

    @RequestMapping("/f4")
    public String f4(){
        return "forward:/showLogin";
    }

    // 在ModelAndView对象中,设置视图名时用法与返回值字符串一致
    @RequestMapping("/f5")
    public ModelAndView f5(){
        ModelAndView mav = new ModelAndView();
        mav.setViewName("forward:/showLogin");
        return mav;
    }

    @RequestMapping("/f6")
    public void f6(){
        System.out.println("LoginController.f6");
        // /WEB-INF/pages/login/f6.jsp
        // /login/f6
        // 将当前的请求名作为视图名返回
    }

    @RequestMapping("/f7")
    public void f7(HttpServletRequest request){
        System.out.println("LoginController.f7");
        // /WEB-INF/pages/login/f7.jsp
        // /login/f7
    }

    @RequestMapping("/f8")
    public void f8(HttpServletResponse response) throws IOException {
        System.out.println("LoginController.f7");
        // 无响应,空白页面
        PrintWriter out = response.getWriter();
        out.print("<h1>Hello World</h1>");
    }

    // 当方法或者方法的返回值使用@ResponseBody进行标注
    // 表示当前的方法不再返回值
    // 其返回值直接作为数据模型返回
    // 即:此时只返回数据,不返回模型
    // 一般用于ajax操作
    // 只有当方法返回值为ModelAndView时,失效
    // 即:方法返回值为ModelAndView时,仍然返回视图与模型
    @ResponseBody
    @RequestMapping("/f9")
    public String f9(){
        return "Hello ResponseBody";
    }

    @RequestMapping("/f10")
    public @ResponseBody String f10(){
        return "<h1>Hello ResponseBody</h1>";
    }

    @RequestMapping("/f11")
    public @ResponseBody ModelAndView f11(){
        ModelAndView mav = new ModelAndView();
        mav.addObject("msg","Hello ResponseBody");
        mav.setViewName("hello");
        return mav;
    }

    @RequestMapping("/f12")
    public void f12(HttpServletRequest request) throws UnsupportedEncodingException {
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username:"+username+",password:"+password);
    }

    // 在Handler中,当方法的参数满足以下条件时,存在默认注解
    // 1.当前方法的参数没有被任何注解所标注
    // 2.当前方法的参数不是一个对象
    // 满足这两个条件,则Spring自动为当前方法的参数添加@RequestParam("参数名")的注解
    @RequestMapping("/f13")
    public void f13(@RequestParam("username") String username,@RequestParam("password") String password){
        System.out.println("username:"+username+",password:"+password);
    }

    @RequestMapping("/f14")
    public void f14(String username,String password){
        System.out.println("username:"+username+",password:"+password);
    }

    // 当required属性值为true时,表示当前参数一定会被Spring处理
    // Spring自动调用request.getParameter("key")的方法
    // 其中参数key为当前注解的value属性值
    // 方法的返回值为注入到对应的参数中
    // 当前required属性值为false时,表示当前参数不是一定会被Spring处理
    // 只有当参数的值不为null时才会处理
    // 即:请求中的数据中包含指定参数的值才会被处理
    @RequestMapping("/f15")
    public void f15(@RequestParam(value = "username",required = false) String username,@RequestParam(value = "password",required = false) String password){
        System.out.println("username:"+username+",password:"+password);
    }

    @RequestMapping("/f16")
    public ModelAndView f16(String username, String password, HttpSession session){
        ModelAndView mav = new ModelAndView();
        // 使用JDBC访问数据的方式将对应的员工信息插入到数据库中
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        String url = "jdbc:mysql://127.0.0.1:3306/ums?useUnicode=true&characterEncoding=utf-8";
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(url,"root","");
            String sql = new StringBuffer()
                    .append(" select id,username,password,phone,address ")
                    .append(" from t_user ")
                    .append(" where username = ? ")
                    .append(" and password = ? ")
                    .toString();
            ps = conn.prepareStatement(sql);
            ps.setString(1,username);
            ps.setString(2,password);
            rs = ps.executeQuery();
            if(rs.next()){
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setPhone(rs.getString("phone"));
                user.setAddress(rs.getString("address"));
                session.setAttribute("user",user);
                mav.setViewName("main");
                return mav;
            }
            mav.addObject("loginMsg","用户名或密码错误");
        } catch (Exception e) {
            e.printStackTrace();
            mav.addObject("loginMsg","服务器内部异常");
        }
        mav.setViewName("login");
        return mav;
    }

}
